# 单元素Quad测试 - 最简单的GPU调试案例
wipe
puts "单元素Quad GPU测试"

model basic -ndm 2 -ndf 2

# 创建4个节点形成一个正方形单元
node 1 0.0 0.0
node 2 1.0 0.0
node 3 1.0 1.0
node 4 0.0 1.0

# 材料
set E 3.0e10
set nu 0.2
set rho 2400.0
nDMaterial ElasticIsotropic 1 $E $nu $rho

# 单个Quad单元
set thickness 1.0
element quad 1 1 2 3 4 $thickness "PlaneStress" 1

# 边界条件：固定底边
fix 1 1 1
fix 2 1 1

# 荷载：顶部节点3施加向下1000N
pattern Plain 1 Linear {
    load 3 0.0 -1000.0
}

puts "模型: 1个单元, 4个节点, 8个DOF (底部2个节点固定)"

# CPU分析
puts "\n=== CPU 分析 ==="
constraints Plain
numberer Plain
system BandGeneral
test NormDispIncr 1.0e-8 50
algorithm Newton
integrator LoadControl 1.0
analysis Static

set ok [analyze 1]

if {$ok == 0} {
    puts "CPU分析成功"
    set cpu_disp_y3 [nodeDisp 3 2]
    set cpu_disp_y4 [nodeDisp 4 2]
    puts "节点3 Y位移: $cpu_disp_y3 m"
    puts "节点4 Y位移: $cpu_disp_y4 m"
} else {
    puts "CPU分析失败"
    set cpu_disp_y3 0.0
    set cpu_disp_y4 0.0
}

# 重建模型
wipe
puts "\n重建模型用于GPU..."
model basic -ndm 2 -ndf 2

node 1 0.0 0.0
node 2 1.0 0.0
node 3 1.0 1.0
node 4 0.0 1.0

nDMaterial ElasticIsotropic 1 $E $nu $rho
element quad 1 1 2 3 4 $thickness "PlaneStress" 1

fix 1 1 1
fix 2 1 1

pattern Plain 1 Linear {
    load 3 0.0 -1000.0
}

# GPU分析
puts "\n=== GPU 分析 ==="
constraints Plain
numberer Plain
system GPUSolver
test NormDispIncr 1.0e-8 50
algorithm Newton
integrator LoadControl 1.0
analysis Static

set ok [analyze 1]

if {$ok == 0} {
    puts "GPU分析成功"
    set gpu_disp_y3 [nodeDisp 3 2]
    set gpu_disp_y4 [nodeDisp 4 2]
    puts "节点3 Y位移: $gpu_disp_y3 m"
    puts "节点4 Y位移: $gpu_disp_y4 m"
} else {
    puts "GPU分析失败"
    set gpu_disp_y3 0.0
    set gpu_disp_y4 0.0
}

# 结果对比
puts "\n=========================================="
puts "单元素Quad - CPU vs GPU结果对比"
puts "=========================================="
puts "材料: E=${E} Pa, nu=${nu}, t=${thickness} m"
puts ""
puts "节点3 Y位移:"
puts "  CPU: $cpu_disp_y3 m"
puts "  GPU: $gpu_disp_y3 m"

if {$cpu_disp_y3 != 0.0 && $gpu_disp_y3 != 0.0} {
    set diff3 [expr abs($cpu_disp_y3 - $gpu_disp_y3)]
    set rel_error3 [expr abs(($gpu_disp_y3 - $cpu_disp_y3) / $cpu_disp_y3) * 100.0]
    puts "  差值: [format %.6e $diff3] m"
    puts "  相对误差: [format %.4f $rel_error3] %"
}

puts ""
puts "节点4 Y位移:"
puts "  CPU: $cpu_disp_y4 m"
puts "  GPU: $gpu_disp_y4 m"

if {$cpu_disp_y4 != 0.0 && $gpu_disp_y4 != 0.0} {
    set diff4 [expr abs($cpu_disp_y4 - $gpu_disp_y4)]
    set rel_error4 [expr abs(($gpu_disp_y4 - $cpu_disp_y4) / $cpu_disp_y4) * 100.0]
    puts "  差值: [format %.6e $diff4] m"
    puts "  相对误差: [format %.4f $rel_error4] %"
}

puts "\n=========================================="
